package lpath

import (
	"fmt"
	"os"
	"os/exec"
	"path/filepath"
	"strings"

	"github.com/pkg/errors"
)

// GetRootPath 获取程序根目录
func GetRootPath() (string, string) {
	proc, err := exec.LookPath(os.Args[0])
	if err != nil {
		panic(fmt.Sprintf("获取程序名失败。err: %v\n", err))
	}

	proc, err = filepath.Abs(proc)
	if err != nil {
		panic(fmt.Sprintf("获取程序路径失败。err: %v\n", err))
	}

	return filepath.Dir(proc), filepath.Base(proc)
}

// MkdirAll 判断，并创建目录
func MkdirAll(path string) error {
	fi, err := os.Stat(path)
	if err == nil {
		if fi.IsDir() {
			return nil
		}
		if err := os.Remove(path); err != nil {
			return err
		}

	}
	if err := os.MkdirAll(path, 0755); err != nil {
		return err
	}
	return nil
}

// SetAbsPath 配置以程序工作目录为根的绝对路径
func SetAbsPath(path string) string {
	rootPath, _ := GetRootPath()
	if !strings.HasPrefix(path, "/") {
		path = filepath.Join(rootPath, path)
	}
	return path
}

// IsDir 是否为目录（存在）
func IsDir(file string) bool {
	fi, err := os.Stat(file)
	if err != nil {
		return false
	}
	if fi.IsDir() {
		return true
	}
	return false
}

func MakeDirs(dirs []string) error {
	for _, dir := range dirs {
		if err := MkdirAll(dir); err != nil {
			return errors.Wrap(err, "创建目录失败")
		}
	}
	return nil
}

func ReadDir(path, extName string) (files []string, err error) {
	des, err := os.ReadDir(path)
	if err != nil {
		return nil, errors.Wrap(err, "遍历目录失败")
	}

	for _, fi := range des {
		if fi.IsDir() {
			continue
		}
		if extName == "" {
			files = append(files, fi.Name())
			continue
		}
		names := strings.Split(fi.Name(), ".")
		if names[len(names)-1] != extName {
			continue
		}
		files = append(files, fi.Name())
	}

	if len(files) == 0 {
		return nil, errors.Errorf("遍历目录: %s,未扫描到所需文件", path)
	}
	return files, nil
}

func ReadDirAll(path string) (files []string, err error) {
	dir, err := os.ReadDir(path)
	if err != nil {
		return nil, fmt.Errorf("读取目录(%s)失败: %v", path, err)
	}
	for _, fi := range dir {
		if fi.IsDir() {
			continue
		}
		files = append(files, fi.Name())
	}
	return
}

func GetAbsDirs(dirs []string, defaultDir string) (absDirs []string) {
	defaultDir = SetAbsPath(defaultDir)
	for _, dir := range dirs {
		dir = strings.TrimSpace(dir)
		if len(dir) == 0 {
			continue
		}
		absDirs = append(absDirs, SetAbsPath(dir))
	}
	if len(absDirs) == 0 {
		absDirs = []string{defaultDir}
	}
	return
}
